<template>
  <div class="layer">
    <input type="text" ref="inputRef" @input="handleInput"
      @compositionend="handleCompositonEnd" @compositionstart="handleCompositonStart">
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'

export default defineComponent({
  name: 'CtrlNumber',
  inheritAttrs: false,
  props: {
    modelValue: {
      type: String,
      default: ''
    }
  },
  data () {
    return {
      isComposing: false
    }
  },
  computed: {
    nativeInputValue () {
      return this.modelValue
    }
  },
  methods: {
    inputRef () {
      return this.$refs.inputRef as HTMLInputElement
    },
    handleInput (event: Event) {
      const target = event.target as HTMLInputElement
      if (this.isComposing) return null
      this.$emit('input', target.value)
      this.$nextTick(() => this.setNativeInputValue())
    },
    setNativeInputValue (value?: string) {
      const inputRef = this.inputRef()
      if (inputRef) inputRef.value = value ?? this.modelValue
    },
    handleCompositonStart (event: Event) {
      this.isComposing = true
      this.$emit('compositionstart', event)
    },
    handleCompositonEnd (event: Event) {
      if (this.isComposing) {
        this.isComposing = false
        this.handleInput(event)
        this.$emit('compositionend', event)
      }
    }
  },
  watch: {
    nativeInputValue: {
      immediate: true,
      handler (newVal) {
        this.$nextTick(() => this.setNativeInputValue(newVal))
      }
    }
  }
})
</script>

<style scoped lang="scss">
.layer {
  margin: 20px;
}
</style>
